import * as cloudDb from '@agconnect/database-server';
import { resource } from './model/resource';
import { topic } from './model/topic';
import { user_topic } from './model/user_topic';
import { user_like } from './model/user_like';
import { user_history } from './model/user_history';
import { TopicResourceResp } from './model/TopicResourceResp';
import { collect } from './model/collect';
import { ResourceResp } from './model/ResourceResp';
import * as agc from '@agconnect/common-server';
import * as Utils from './utils/Utils.js';

const ZONE_NAME = "HarmonyOSDeveloper";

export class DatabaseHelper {
  logger;
  cloudDbZone;

  constructor(context, logger) {
    this.logger = logger;
    const credential = Utils.getCredential(context, logger);
    try {
      // 初始化AGCClient
      logger.info("begin to init agcClient");
      let agcClient;
      try {
        agcClient = agc.AGCClient.getInstance();
      } catch {
        agc.AGCClient.initialize(credential);
        agcClient = agc.AGCClient.getInstance();
      }
      // 初始化AGConnectCloudDB实例
      logger.info("begin to init cloudDb");
      let cloudDbInstance;
      try {
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      } catch {
        cloudDb.AGConnectCloudDB.initialize(agcClient);
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      }
      // 创建CloudDBZoneConfig配置对象，并设置云侧CloudDB zone名称，打开Cloud DB zone实例
      const cloudDBZoneConfig = new cloudDb.CloudDBZoneConfig(ZONE_NAME);
      this.cloudDbZone = cloudDbInstance.openCloudDBZone(cloudDBZoneConfig);
    } catch (err) {
      logger.error("init CloudDBZoneWrapper error: " + err);
    }
  }

  async queryResource(userid, type) {
    let respData: TopicResourceResp[] = [];
    let topicData = [];
    let topicNme = [];
    let likedIds = [];
    let collectedIds = [];
    let historyIds = [];
    let topicIds = []
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      // 2 然后根据topic等条件筛选
      const resourceQuery = cloudDb.CloudDBZoneQuery.where(resource);
      // 先查询该userid关联了哪些topic
      const topicQuery = cloudDb.CloudDBZoneQuery.where(user_topic).equalTo('user_id', userid);
      const topicResp = await this.cloudDbZone.executeQuery(topicQuery);
      topicData = topicResp.getSnapshotObjects();
      this.logger.info("query user success ");
      console.log('resp=>', topicData);

      for (let i = 0; i < topicData.length; i++) {
        topicIds.push(topicData[i].getTopic_id())
      }
      likedIds = await this.queryLikedIds(userid);
      collectedIds = await this.queryCollectedIds(userid);
      historyIds = await this.queryHistoryIds(userid);
      //TODO 多个主题对应多篇文章 该怎么实现？
      resourceQuery.in('topics', topicIds);
      let topics: topic[] = await this.queryTopic();
      resourceQuery.notEqualTo('tag', 3) // 不为hot
      resourceQuery.equalTo('type', type);

      const resResp = await this.cloudDbZone.executeQuery(resourceQuery);
      // resourceQuery.limit(100, 4).orderByDesc("views_count").orderByDesc("publish_date"); // 普通
      // const recommendResp = await this.cloudDbZone.executeQuery(resourceQuery);

      // let topPicksData: resource[] = topPicksResp.getSnapshotObjects();
      // let recommendData: resource[] = recommendResp.getSnapshotObjects();
      let resData: resource[] = resResp.getSnapshotObjects();

      // 筛选用户关注主题中类型为topic的主题
      let topsss = this.getTopicTopic(topics, topicIds)
      for (let i = 0; i < topsss.length; i++) {
        let topic: topic = topsss[i];
        let topicResourceResp: TopicResourceResp = new TopicResourceResp();
        topicResourceResp.topicId = topic.getId();
        topicResourceResp.topicName = topic.getName();

        let datas = this.filterResourceData(resData, topic.getId(), likedIds, collectedIds, historyIds, topics);

        topicResourceResp.topPicksList = datas[0];
        topicResourceResp.recommendList = datas[1];

        if (topicResourceResp.topPicksList && topicResourceResp.topPicksList.length > 0) {
          respData.push(topicResourceResp);
        }
      }
      return respData;

    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  filterResourceData(resourceList: resource[], topicId: string, likedIds, collectedIds, historyIds, topics) {
    let resList: ResourceResp[] = [];
    for (let index = 0; index < resourceList.length; index++) {
      const dataQ: resource = resourceList[index];
      if (topicId === dataQ.getTopics()) {
        resList.push(new ResourceResp(
          dataQ.getId(),
          dataQ.getTitle(),
          dataQ.getBrief(),
          dataQ.getHeader_src(),
          dataQ.getType(),
          dataQ.getWeb_url(),
          dataQ.getPublish_date(),
          [this.getTopicName(topics, dataQ.getTopics())],
          dataQ.getViews_count(),
          dataQ.getCollect_count(),
          dataQ.getLikes_count(),
          dataQ.getTag(),
          dataQ.getBanner_src(),
          dataQ.getMedia_src(),
          likedIds.indexOf(dataQ.getId()) !== -1, // isLiked
          collectedIds.indexOf(dataQ.getId()) !== -1, // isCollected
          historyIds.indexOf(dataQ.getId()) !== -1 // isViewed
        ))
      }
    }
    // 前四的按热度
    // 使用排序方法对数组进行排序
    let filteredArray1 = [];
    let filteredArray2 = [];
    if (resList.length >= 4) {
      let sortedArray = resList.sort((a: ResourceResp, b: ResourceResp) => b.viewsCount - a.viewsCount);
      // 使用slice方法取出前四个元素
      filteredArray1 = sortedArray.slice(0, 4);
      // 后面的按时间排序
      let commonArray=sortedArray.slice(4);
      filteredArray2= commonArray.sort((a: ResourceResp, b: ResourceResp) => b.publishDate - a.publishDate);
    }else{
      filteredArray1=resList;
    }
    return [filteredArray1,filteredArray2];
  }

  async queryLikedIds(userid) {
    let likedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const likeQuery = cloudDb.CloudDBZoneQuery.where(user_like);
      likeQuery.equalTo('user_id', userid);
      const likeResp = await this.cloudDbZone.executeQuery(likeQuery);
      let likeData = likeResp.getSnapshotObjects();
      this.logger.info("query like resource success ");
      console.log('resp like=>', likeResp);
      for (let index = 0; index < likeData.length; index++) {
        const element: user_like = likeData[index];
        likedIds.push(element.getResource_id());
      }
      return likedIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryCollectedIds(userid) {
    let collectedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const collectedQuery = cloudDb.CloudDBZoneQuery.where(collect);
      collectedQuery.equalTo('user_id', userid);
      const collectedResp = await this.cloudDbZone.executeQuery(collectedQuery);
      let collectedData = collectedResp.getSnapshotObjects();
      this.logger.info("query collected resource success ");
      console.log('resp collected=>', collectedResp);
      for (let index = 0; index < collectedData.length; index++) {
        const element: collect = collectedData[index];
        collectedIds.push(element.getResource_id());
      }
      return collectedIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryHistoryIds(userid) {
    let historyIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const historyQuery = cloudDb.CloudDBZoneQuery.where(user_history);
      historyQuery.equalTo('user_id', userid);
      const historyResp = await this.cloudDbZone.executeQuery(historyQuery);
      let historyData = historyResp.getSnapshotObjects();
      this.logger.info("query historyData resource success ");
      console.log('resp historyData=>', historyResp);
      for (let index = 0; index < historyData.length; index++) {
        const element: user_history = historyData[index];
        historyIds.push(element.getResource_id());
      }
      return historyIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryTopic() {
    // 查询所有主题
    const cloudDBZoneQuery = cloudDb.CloudDBZoneQuery.where(topic);
    const resp = await this.cloudDbZone.executeQuery(cloudDBZoneQuery);
    let listData = resp.getSnapshotObjects();
    this.logger.info("query topic success ");
    console.log('resp=>', resp.getSnapshotObjects());
    return listData;
  }

  getTopicName(topics: topic[], tid) {
    let top = topics.filter(tp => tp.getId() === tid);
    return top[0].getName();
  }

  getTopicTopic(topics: topic[], topicIds: string[]) {
    // 先筛选出类型为type的主题
    let topics1 = topics.filter(tp => tp.getType() === 'topic');
    // 再筛选出其中关注的主题
    let topics2 = topics1.filter(tp => topicIds.indexOf(tp.getId()) !== -1);
    return topics2;
  }
}

